package vendas.business;

import gminet.infra.business.BusinessException;
import gminet.infra.business.BusinessObject;
import gminet.infra.db.Transaction;
import gminet.infra.db.TransactionException;

import java.sql.Connection;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import vendas.dao.OrderDAO;
import vendas.dao.OrderFilter;
import vendas.dto.ActionType;
import vendas.dto.Order;
import vendas.dto.OrderStatus;
import vendas.dto.PaymentStatus;
import vendas.dto.SellStatus;
import vendas.dto.User;


public class OrderBusiness extends BusinessObject {

    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyMMdd");

    public static Order findByPK(int userId, int orderId) throws BusinessException, TransactionException {

        Order order = null;
        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            order = OrderDAO.findByPK(userId, orderId, conn);
            if (order == null) {
                throw new BusinessException("Pedido não encontrado.");
            }
        } finally {
            transaction.release();
        }
        return order;
    }

    public static List<Order> findAll(int userId, boolean pendentOnly) throws TransactionException {

        List<Order> orders = null;
        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            orders = OrderDAO.findAll(userId, conn);
        } finally {
            transaction.release();
        }
        return orders;
    }
    
    public static List<Order> findPendentOnly(int userId) throws TransactionException {
        
        return findByFilter(userId, null, true);
    }

    public static List<Order> findByFilter(int userId, OrderFilter filter) throws TransactionException {

        return findByFilter(userId, filter, false);
    }

    private static List<Order> findByFilter(int userId, OrderFilter orderFilter, boolean pendentOnly) throws TransactionException {

        List<Order> orders = null;
        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            if (orderFilter != null) {
                orderFilter.setUser(new User(userId));
            }
            orders = OrderDAO.findByFilter(orderFilter, pendentOnly, conn);
        } finally {
            transaction.release();
        }
        return orders;
    }

    public static Order insert(Order order) throws BusinessException, TransactionException {

        Order newOrder = null;
        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            int userId = order.getUser().getId();
            // ORDER
            int rangeOrderId = createRangeOrderId(order.getOrderDate());
            int orderId = OrderDAO.getNextCodigo(conn, userId, rangeOrderId, rangeOrderId + 100);
            order.setId(orderId);
            order.setStatus(OrderStatus.ORDERED);
            order.setPaymentStatus(PaymentStatus.UNPAY);
            OrderDAO.insert(order, conn);
            // COMMIT
            transaction.commit();
            //
            newOrder = order;
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
        return newOrder;
    }

    private static int createRangeOrderId(Date orderDate) {

        String strCodigo = DATE_FORMAT.format(orderDate);
        strCodigo += "00";
        return Integer.parseInt(strCodigo);
    }

    public static void update(Order order) throws BusinessException, TransactionException {

        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            OrderDAO.update(order, conn);
            // COMMIT
            transaction.commit();
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
    }
    
    public static void updateStatus(Order order, ActionType actionType) throws BusinessException, TransactionException {

        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            Order auxOrder = OrderDAO.findByPK(order.getUser().getId(), order.getId(), conn);
            if (actionType.equals(ActionType.ARRIVE_ITEM)) {
                auxOrder.setArriveDate(order.getArriveDate());
                auxOrder.setStatus(OrderStatus.RECEIVED);
            } else if (actionType.equals(ActionType.SELL_ITEM)) {
                auxOrder.setSellDate(order.getSellDate());
                auxOrder.setSellValue(order.getSellValue());
                auxOrder.setSellStatus(order.getSellStatus());
                auxOrder.setStatus(OrderStatus.SOLD);
                auxOrder.setBuyer(order.getBuyer());
                auxOrder.setBuyerType(order.getBuyerType());
            } else if (actionType.equals(ActionType.RECEIVE_PAYMENT)) {
                auxOrder.setSellStatus(SellStatus.RECEIVE_PAYMENT);
            } else if (actionType.equals(ActionType.PAY_ITEM)) {
                auxOrder.setPaymentDate(order.getPaymentDate());
                auxOrder.setCurrencyValue(order.getCurrencyValue());
                auxOrder.setBuyValue(order.getBuyValue());
                auxOrder.setShippingValue(order.getShippingValue());
                auxOrder.setTaxValue(order.getTaxValue());
                auxOrder.setPaymentStatus(PaymentStatus.PAY);
            }
            OrderDAO.update(auxOrder, conn);
            // COMMIT
            transaction.commit();
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
    }

    public static void delete(Order order) throws BusinessException, TransactionException {

        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            // ORDER
            OrderDAO.delete(order, conn);
            transaction.commit();
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
    }

}
